package com.dm.contriller;

import com.alibaba.fastjson.JSON;
import com.dm.client.dm_base.RestDmImageClient;
import com.dm.client.dm_user.RestDmUserClient;
import com.dm.common.EmptyUtils;
import com.dm.common.MD5;
import com.dm.common.RedisUtils;
import com.dm.common.UrlUtils;
import com.dm.config.WechatConfig;
import com.dm.dto.Dto;
import com.dm.dto.DtoUtil;
import com.dm.exception.ErrorCode;
import com.dm.pojo.dm_base.DmImage;
import com.dm.pojo.dm_user.DmUser;
import com.dm.service.use_token.TokenService;
import com.dm.service.user_login.LoginDmUser;
import com.dm.vo.DmUserVO;
import com.sun.org.glassfish.external.statistics.annotations.Reset;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by hai.dong on 2018/11/19.
 */
@RestController
@RequestMapping("/api/wechatlogin")
public class WechatController {
    @Resource
    private WechatConfig wechatConfig;
    @Resource
    private RestDmUserClient restDmUserClient;
    @Resource
    private RestDmImageClient restDmImageClient;

    @Resource
    private TokenService tokenService;
    @Resource
    private LoginDmUser loginDmUser;


    /**
     * 微信登录第一步：请求获取code
     *
     * @throws Exception
     */
    @RequestMapping("/wechat/login")
    public void wechatLogin(HttpServletResponse response) throws Exception {
        //拼写请求获取code的地址
        String redirect_uri = "http://localhost:8080/api/wechatlogin/wechat/callBack";
        StringBuilder codeUrl = new StringBuilder("https://open.weixin.qq.com/connect/qrconnect");
        codeUrl.append("?appid=" + wechatConfig.getAppId());
        codeUrl.append("&redirect_uri=" + java.net.URLEncoder.encode(redirect_uri, "UTF-8"));
        codeUrl.append("&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect");
        //发送请求
        response.sendRedirect(codeUrl.toString());
    }

    /**
     * 微信登录第二步：请求获取access_token
     *
     * @param code
     * @throws Exception
     */
    @RequestMapping("/wechat/callBack")
    public Dto wechatCallBack(@RequestParam String code, @RequestParam String state, HttpServletResponse response) throws Exception {
        DmUser dmUser=null;
        DmImage dmImage=null;
        DmUserVO dmUserVO=new DmUserVO();
        //=====1:获得code.u可以校验是否为null
        if (EmptyUtils.isEmpty(code)) {
            return DtoUtil.returnFail(ErrorCode.Wechat_Accredit_NO.getErrorMessage(), ErrorCode.Wechat_Accredit_NO.getErrorCode());
        }

        //=====2:联合appid、appsecret、code换取access_token
        StringBuilder tokenUrl = new StringBuilder("https://api.weixin.qq.com/sns/oauth2/access_token");
        tokenUrl.append("?appid=" + wechatConfig.getAppId());
        tokenUrl.append("&secret=" + wechatConfig.getSecret());
        tokenUrl.append("&code=" + code);
        tokenUrl.append("&grant_type=authorization_code");

        //=====3:加载地址获取token等信息
        String json = UrlUtils.loadURL(tokenUrl.toString());
        Map<String, Object> tokenMap = new HashMap<String, Object>();
        tokenMap = JSON.parseObject(json, Map.class);

        //=====4:用户注册的问题，是否是首次微信账户登录，如果是，insert用户信息
        //判断是否加载返回错误
        if(tokenMap.get("errcode")==null){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("wxUserId",tokenMap.get("openid"));
            List<DmUser> list=restDmUserClient.getDmUserListByMap(map);

            //是否注册过
           if(0==list.size()||null==list){
               // 进行第四步：请求获取用户信息
               StringBuilder userInfoUrl = new StringBuilder("https://api.weixin.qq.com/sns/userinfo");
               userInfoUrl.append("?access_token=" + tokenMap.get("access_token").toString());
               userInfoUrl.append("&openid=" + tokenMap.get("openid").toString());
               //发送请求获取用户信息
               String userInfoJson = UrlUtils.loadURL(userInfoUrl.toString());
               Map<String, Object> userInfoMap = new HashMap<String, Object>();
               userInfoMap = JSON.parseObject(userInfoJson, Map.class);

               //创建用户对象添加信息并添加数据库
                dmUser=new DmUser();
                dmUser.setWxUserId(userInfoMap.get("openid").toString());
                dmUser.setSex(Integer.valueOf(userInfoMap.get("sex").toString()));
                dmUser.setNickName(userInfoMap.get("nickname").toString());
                restDmUserClient.qdtxAddDmUser(dmUser);
                //获取主键
               Map<String, Object> idMap = new HashMap<String, Object>();
               idMap.put("wxUserId",userInfoMap.get("openid"));
                dmUser=restDmUserClient.getDmUserListByMap(idMap).get(0);
                //添加用户头像图片
               dmImage=new DmImage();
               dmImage.setImgUrl(userInfoMap.get("headimgurl").toString());
               dmImage.setCategory(0);
               dmImage.setType(0);
               dmImage.setTargetId(Integer.valueOf(dmUser.getId().toString()));
               restDmImageClient.qdtxAddDmImage(dmImage);
           }else{
               dmUser=list.get(0);
           }
        }else{
            return DtoUtil.returnFail(ErrorCode.Wechat_Accredit_Fail.getErrorMessage(), ErrorCode.Wechat_Accredit_Fail.getErrorCode());

        }
        //=====5:本站token设置
        BeanUtils.copyProperties(dmUser,dmUserVO);
        dmUserVO.setUserId(dmUser.getId());
        dmUserVO.setHeadimgUrl(dmImage.getImgUrl());
        //：判断有无token
        String tokenKey = tokenService.validateToken(dmUserVO.getUserId().toString());
        //无token
        if (EmptyUtils.isEmpty(tokenKey)) {
            //=====1:生成token并储存redis
            //生成token
            tokenKey = this.getToken("PC", dmUserVO);
            //储存token
            tokenService.saveTokenById(dmUserVO.getUserId().toString(), tokenKey);
            tokenService.saveToken(tokenKey, dmUserVO);
        }

        //返回用户信息和token到客户端
        return DtoUtil.returnSuccess(ErrorCode.LOGIN_SUCCESS.getErrorMessage(),loginDmUser.mergeByUser_Token(tokenKey, dmUserVO));
    }



    public String getToken(String agent, DmUserVO user) throws Exception {


       /*
        token:PC-3066014fa0b10792e4a762-23-20170531133947-4f6496
        前缀: token:
        终端类型: PC / MOBILE
        userCode信息(MD5混淆) : 32位
        userID:来自数据库
        Token创建时间: yyyMddHmmss
        最后6位根据User-Agent MD5混淆: 6位验证码
        */


        StringBuilder stringBuilder = new StringBuilder("token:"+agent+"-");
        //Personal computer ----->PC

        //追加根据用户编号生成32为MD5号码
        stringBuilder.append(MD5.getMd5(user.getWxUserId(), 32) + "-");

        //追加用户id
        stringBuilder.append(user.getUserId() + "-");

        //拼接当前时间段
        stringBuilder.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));

        //根据设备类型生成6为号码
        stringBuilder.append("-" + MD5.getMd5(agent, 6));

        return stringBuilder.toString();
    }
}